<template>
  <div id="app-container">
    <div id="header" ref="header">
      <div>
        <ul>
          <li class="control">
            <a @click="handleOpen()" type="button">
              <input class="openFile" type="file" @change="onOpenFile($event)">
              <i class="el-icon-folder-opened" />
              导入
            </a>
          </li>
          <li class="control">
            <a @click="handleSave()" type="button">
              <i class="el-icon-folder" />
              保存
            </a>
          </li>
          <el-divider direction="vertical"></el-divider>
          <li class="control">
            <a @click="validateDiagrame('bottom')" type="button">
              <i class="el-icon-check" />
              验证
            </a>
          </li>
          <el-divider direction="vertical"></el-divider>
          <li class="control">
            <a @click="handleUndo()" type="button">
              <i class="undo" />
              撤销
            </a>
          </li>
          <li class="control">
            <a @click="handleRedo()" type="button">
              <i class="redo" />
              重做
            </a>
          </li>
          <el-divider direction="vertical"></el-divider>
          <li class="control">
            <a @click="handleZoom()" type="button">
              <i class="el-icon-aim" />
              缩放到实际尺寸
            </a>
          </li>
          <li class="control">
            <a @click="handleZoom(0.1)" type="button">
              <i class="el-icon-circle-plus-outline" />
              放大
            </a>
          </li>
          <li class="control">
            <a @click="handleZoom(-0.1)" type="button">
              <i class="el-icon-remove-outline" />
              缩小
            </a>
          </li>
          <el-divider direction="vertical"></el-divider>
          <li class="control">
            <a @click="handleDownloadXml()" type="button">
              <i class="el-icon-download" />
              下载BPMN流程图
            </a>
          </li>
          <li class="control">
            <a @click="handleDownloadSvg()" type="button">
              <i class="el-icon-picture" />
              下载SVG图片
            </a>
          </li>
          <el-divider direction="vertical"></el-divider>
          <li class="control">
            <a @click="handleFullScreen()" type="button">
              <i class="el-icon-full-screen" />
              全屏/退出
            </a>
          </li>
          <el-divider direction="vertical"></el-divider>
          <li class="control">
            <a @click="showShortcutKeys()" type="button">
              <i class="keyboard" />
              快捷键
            </a>
          </li>
          <el-divider direction="vertical"></el-divider>
          <li class="control">
            <a @click="autuLayout()" type="button">
              <i class="autoAlign" />
              自动排版
            </a>
          </li>
          <li class="control">
            <a @click="align('left')" type="button">
              <i class="alignLeft" />
              左对齐
            </a>
          </li>
          <li class="control">
            <a type="button" @click="align('middle')">
              <i class="alignMiddle" />
              水平对齐
            </a>
          </li>
          <li class="control">
            <a type="button" @click="align('right')">
              <i class="alignRight" />
              右对齐
            </a>
          </li>
          <li class="control">
            <a @click="align('top')" type="button">
              <i class="alignTop" />
              顶部对齐
            </a>
          </li>
          <li class="control">
            <a @click="align('center')" type="button">
              <i class="alignCenter" />
              垂直对齐
            </a>
          </li>
          <li class="control">
            <a @click="align('bottom')" type="button">
              <i class="alignBottom" />
              底部对齐
            </a>
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'ukulele-bpmn-header',
  components: {

  },
  props: {
    bpmnModeler: {
      type: Object,
      required: true
    },
    processInfo: {
      type: Object,
      require: true,
      default: null
    }
  },
  data() {
    return {

      state: {
        scale: 1 // 流程图比例
      },
      processDiagramXml: ''
    }
  },
  computed: {

  },
  mounted() {
  },
  methods: {
    /**
     * 下载xml/svg
     *  @param  type  类型  svg / xml
     *  @param  data  数据
     *  @param  name  文件名称
     */
    download(type, data, name) {
      let dataTrack = ''
      const a = document.createElement('a')
      switch (type) {
        case 'xml':
          dataTrack = 'bpmn'
          break
        case 'svg':
          dataTrack = 'svg'
          break
        default:
          break
      }
      const bpmnName =
        this.bpmnModeler._definitions.rootElements[0].name ||
        this.bpmnModeler._definitions.rootElements[0].id
      const filename = bpmnName + '.' + dataTrack

      name = name || `${filename}`

      a.setAttribute(
        'href',
        `data:application/bpmn20-xml;charset=UTF-8,${encodeURIComponent(data)}`
      )
      a.setAttribute('target', '_blank')
      a.setAttribute('dataTrack', `diagram:download-${dataTrack}`)
      a.setAttribute('download', name)

      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
    },

    // 导入xml文件
    handleOpenFile(e) {
      const that = this
      const file = e.target.files[0]
      const reader = new FileReader()
      let data = ''
      reader.readAsText(file)
      reader.onload = function(event) {
        data = event.target.result
        that.renderDiagram(data)
      }
    },
    async renderDiagram(xml) {
      try {
        const result = await this.bpmnModeler.importXML(xml);
        const { warnings } = result;
        console.log(warnings);
        const transactionBoundaries = this.bpmnModeler.get('transactionBoundaries');
        transactionBoundaries.show();
      } catch (err) {
        console.log(err.message, err.warnings);
      }
    },
    // 保存
    async handleSave() {
      try {
        const result = await this.bpmnModeler.saveXML({ format: true });
        console.log(result);
        const nodeIdList = []
        try {
          for (const index in this.bpmnModeler._definitions.$model.ids._seed.hats) {
            if (this.bpmnModeler._definitions.$model.ids._seed.hats[index].$type === 'bpmn:Process') continue
            nodeIdList.push(this.bpmnModeler._definitions.$model.ids._seed.hats[index].id)
          }
        } catch (e) {
          console.error(e)
        }

        try {
          const nodeList = []
          for (const index2 in this.bpmnModeler.get('elementRegistry').getAll()) {
            if (this.bpmnModeler.get('elementRegistry').getAll()[index2].type === 'label' ||
            this.bpmnModeler.get('elementRegistry').getAll()[index2].type === 'bpmn:Process') continue
            // nodeList.push(this.$refs.panel.elementToNodeInfo(this.bpmnModeler.get('elementRegistry').getAll()[index2]))
          }
          console.log('nodeList:' + JSON.stringify(nodeList))
        } catch (e) {
          console.error(e)
        }

        if (!this.bpmnModeler.get('linting')._active) {
          this.bpmnModeler.get('linting').toggle()
          this.$message.warning('当前流程未校验，现自动开启校验，如果校验无误后，请再点击保存按钮！')
          // return 报错但暂时允许保存
        }
        const validateError = Number(this.bpmnModeler.get('linting')._button.innerText.split(' Errors')[0])
        console.log('validateError:' + validateError)
        if (validateError > 0) {
          this.$message.error('当前流程未通过校验，请修改后再保存！')
        }
        const postData = {
          tenantId: this.processInfo.tenantId,
          processId: this.processInfo.processId,
          processName: this.processInfo.processName,
          processKey: this.processInfo.processKey,
          processXml: result.xml.replace(/ns0:/g, 'activiti:')
        }
        this.$emit('save', postData)
        console.log('header调用了save')
      } catch (err) {
        this.$message.error(err);
      }
    },
    // 前进
    handleRedo() {
      this.bpmnModeler.get('commandStack').redo()
    },

    // 后退
    handleUndo() {
      this.bpmnModeler.get('commandStack').undo()
    },

    // 对齐
    align(type) {
      const selection = this.bpmnModeler.get('selection').get()

      if (selection === 'undefined' || selection === null || selection === '' || selection.length === 0) {
        this.$message.error('选择排版节点为空，请选择需对齐具体节点！')
        return
      }
      this.bpmnModeler.get('alignElements').trigger(selection, type)
    },

    // 下载SVG格式
    async handleDownloadSvg() {
      try {
        const result = await this.bpmnModeler.saveSVG({ format: true });
        this.download('svg', result.svg)
        this.processDiagramSvg = result.svg;
      } catch (err) {
        this.$message.error(err);
      }
    },

    // 下载XML格式
    async handleDownloadXml() {
      try {
        const result = await this.bpmnModeler.saveXML({ format: true });
        this.download('xml', result.xml.replace(/ns0:/g, 'activiti:'))
      } catch (err) {
        this.$message.error(err);
      }
    },

    // 流程图放大缩小
    handleZoom(radio) {
      console.log('handleZoom () ')
      const newScale = !radio
        ? 1.0 // 不输入radio则还原
        : this.state.scale + radio <= 0.2 // 最小缩小倍数
          ? 0.2
          : this.state.scale + radio
      this.bpmnModeler.get('canvas').zoom(newScale)
      this.state.scale = newScale
    },

    handleOpen() {
      document.getElementsByClassName('openFile')[0].click()
    },
    onOpenFile(files) {
      this.handleOpenFile(files)
    },
    handleFullScreen() {
      const element = document.documentElement
      // 判断是否已经是全屏
      // 如果是全屏，退出
      if (this.fullscreen) {
        if (document.exitFullscreen) {
          document.exitFullscreen()
        } else if (document.webkitCancelFullScreen) {
          document.webkitCancelFullScreen()
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen()
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen()
        }
      } else {
        // 否则，进入全屏
        if (element.requestFullscreen) {
          element.requestFullscreen()
        } else if (element.webkitRequestFullScreen) {
          element.webkitRequestFullScreen()
        } else if (element.mozRequestFullScreen) {
          element.mozRequestFullScreen()
        } else if (element.msRequestFullscreen) {
          // IE11
          element.msRequestFullscreen()
        }
      }
      // 改变当前全屏状态
      this.fullscreen = !this.fullscreen
    },
    showShortcutKeys() {
      const showcutKeysHtml =
        '<table>' +
        '<tbody>' +
        '<tr>' +
        '<td>撤销</td>' +
        '<td class="binding"><code>ctrl + Z</code></td>' +
        '</tr>' +
        '<tr>' +
        '<td>重做</td>' +
        '<td class="binding"><code>ctrl + ⇧ + Z</code></td>' +
        '</tr>' +
        '<tr>' +
        '<td>全选</td>' +
        '<td class="binding"><code>ctrl + A</code></td>' +
        '</tr>' +
        '<tr>' +
        '<td>滚动（垂直）</td>' +
        '<td class="binding"><code>ctrl + Scrolling</code></td>' +
        '</tr>' +
        '<tr>' +
        '<td>滚动（水平）</td>' +
        '<td class="binding"><code>ctrl + ⇧ + Scrolling</code></td>' +
        '</tr>' +
        '<tr>' +
        '<td>直接编辑</td>  ' +
        '<td class="binding"><code>E</code></td>' +
        '</tr>' +
        '<tr>' +
        '<td>拖拽工具</td>' +
        '<td class="binding"><code>H</code></td>' +
        '</tr>' +
        '<tr>' +
        '<td>自由套索工具</td>' +
        '<td class="binding"><code>L</code></td>' +
        '</tr>' +
        '<tr>' +
        '<td>空间移动工具</td>' +
        '<td class="binding"><code>S</code></td>' +
        '</tr>' +
        '</tbody>' +
        '</table>'

      this.$alert(showcutKeysHtml, '快捷键', {
        dangerouslyUseHTMLString: true
      }).catch(e => e)
    },
    async autuLayout() {
      this.getProcessDiagramXML()
      const AutoLayout = require('../fix/bpmn-auto-layout').default
      const autoLayout = new AutoLayout()
      try {
        const result = await this.bpmnModeler.saveXML({ format: true });
        await autoLayout.layoutProcess(result.xml)
      } catch (err) {
        this.$message.error(err);
      }
    },
    async getProcessDiagramXML() {
      if (this.bpmnModeler._customElements != null && this.bpmnModeler._customElements.length > 0) {
      // 将自定义的元素 加入到 _definitions
        // eslint-disable-next-line vue/no-mutating-props
        this.bpmnModeler._definitions.rootElements[0].flowElements =
          this.bpmnModeler._definitions.rootElements[0].flowElements.concat(this.bpmnModeler._customElements[0])
      }
      try {
        const result = await this.bpmnModeler.saveXML({ format: true });
        this.processDiagramXml = result.xml.replace(/ns0:/g, 'activiti:')
      } catch (err) {
        this.$message.error(err);
      }
    },
    async getProcessDiagramSvg() {
      try {
        const result = await this.bpmnModeler.saveSVG({ format: true });
        this.processDiagramSvg = result.svg;
      } catch (err) {
        this.$message.error(err);
      }
    },
    validateDiagrame() {
      this.bpmnModeler.get('linting').toggle()
    }
  }
}
</script>

<style>
a, a:focus, a:hover {
  cursor: pointer;
  color: inherit;
  text-decoration: none;
}

a {
  background-color: transparent;
  -webkit-text-decoration-skip: objects;
}

.control {
  position: relative;
  display: inline-block;
  padding: 5px 5px;
  list-style-type: none;
}

.control a {
  font-size: 14px;
  color: black;
}

.control button {
  padding: 0;
  outline: none;
  cursor: pointer;
  font-size: 22px;
  line-height: 26px;
  color: #555;
  background: none;
  border: none;

}

.control .openFile {
  display: none
}

.control.line:after {
  content: '';
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  height: 16px;
  border-right: 1px solid #ddd
}

.control a i {
  display: inline-block;
  width: 16px;
  height: 16px;
  vertical-align: middle;
  font-style: none
}

.drop-overlay {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;

  padding: 50px;

  background: rgba(255, 255, 255, 0.96);

  z-index: 1000;
}

.drop-overlay .box {
  text-align: center;
  border: dashed 4px #ccc;
  border-radius: 20px;
  height: 100%;

  display: flex;
  align-content: middle;

  pointer-events: none;
}

.drop-overlay .label {
  font-size: 26px;
  color: #888;
  margin: auto;
}

.showBPMNXML {
  height: 100%;
  width: 100%;
  font-size: 14px;
}

pre {
  display: block;
  font-family: monospace;
  white-space: pre;
  margin: 1em 0px;
  height: 100%;
  width: 100%;
}

.hljs {
  display: block;
  overflow-x: auto;
  background: #fefefe;
  color: #545454;
  padding: 0.5em;
  height: 100%;
  width: 100%;
}

.el-input {
  position: relative;
  font-size: 14px;
  display: inline-block;
}

.zoom {
  cursor: pointer;
  background: url("../assets/diagram_images/zoom.svg") 0 0 no-repeat;
}

.zoomIn {
  cursor: pointer;
  background: url("../assets/diagram_images/zoomIn.svg") 0 0 no-repeat;
}

.zoomOut {
  cursor: pointer;
  background: url("../assets/diagram_images/zoomOut.svg") 0 0 no-repeat;
}

.undo {
  cursor: pointer;
  background: url("../assets/diagram_images/undo.svg") 0 0 no-repeat;
}

.redo {
  cursor: pointer;
  background: url("../assets/diagram_images/redo.svg") 0 0 no-repeat;
}

.save {
  cursor: pointer;
  background: url("../assets/diagram_images/save.svg") 0 0 no-repeat;
}

.download {
  cursor: pointer;
  background: url("../assets/diagram_images/download.svg") 0 0 no-repeat;
}

.image {
  cursor: pointer;
  background: url("../assets/diagram_images/image.svg") 0 0 no-repeat;
}

.fullscreen {
  cursor: pointer;
  background: url("../assets/diagram_images/fullscreen.svg");
}

.keyboard {
  cursor: pointer;
  background: url("../assets/diagram_images/keyboard.svg");
}

.autoAlign {
  cursor: pointer;
  background: url("../assets/diagram_images/autoAlign.svg");
}

.openFileIcon {
  cursor: pointer;
  background: url("../assets/diagram_images/open.svg") 0 0 no-repeat;
}

.alignLeft {
  cursor: pointer;
  background: url("../assets/diagram_images/left.svg") 0 0 no-repeat;
}

.alignCenter {
  cursor: pointer;
  background: url("../assets/diagram_images/center.svg") 0 0 no-repeat;
}

.alignRight {
  cursor: pointer;
  background: url("../assets/diagram_images/right.svg") 0 0 no-repeat;
}

.alignTop {
  cursor: pointer;
  background: url("../assets/diagram_images/top.svg") 0 0 no-repeat;
}

.alignMiddle {
  cursor: pointer;
  background: url("../assets/diagram_images/middle.svg") 0 0 no-repeat;
}

.alignBottom {
  cursor: pointer;
  background: url("../assets/diagram_images/bottom.svg") 0 0 no-repeat;
}

.validate {
  cursor: pointer;
  background: url("../assets/diagram_images/validate.svg") 0 0 no-repeat;
}
</style>
